Memory devices are important components of many integrated circuits or products having integrated circuits. Because memories are so significant to the operation of these devices, it is important that data stored in a memory device can be correctly accessed. Data can be written to a memory and read from a memory using a single clock signal. Such memories enable synchronous data transfers. However, data could also be asynchronously transferred in memory devices which receive data and output data using two separate asynchronous clocks. Asynchronous clocks not only have a different phase, but also have a different frequency.
Memory devices also have various protocols for outputting stored data. For example, a first-in first-out (FIFO) memory is a memory device where a data sequence can be written to and retrieved from the memory in exactly the same order. Because no explicit addressing is required, the write and read operations can be completely independent and use unrelated clocks. While the concept of a FIFO is simple, the implementation of an asynchronous FIFO in an integrated circuit is often difficult. One common implementation of an asynchronous FIFO is a random access memory (RAM) having two independently clocked ports (i.e. one for writing and one for reading), and two independent address counters to steer write and read data. However, synchronizing and decoding the two ports operating at two asynchronous frequencies can require significant engineering effort to ensure that they are tolerant to variations in clock signals.
Conventional clock tolerant FIFOs implement a mechanism in which an idle data block is either removed or inserted dependent upon how full or empty the FIFO is at a particular time. The decision to remove or insert idle data blocks according to conventional devices is either made on the read side or the write side of the FIFO. The decision circuit determines whether to remove or insert an idle, and then performs the action by modifying the address counter or multiplexing in data. However, such conventional devices require additional circuitry, such as a variable increment address counters enabling incrementing an addresses pointer by a variable number at the output of the FIFO depending upon how many data blocks were removed at an input to a FIFO. Further, the circuit on the read side for preventing the memory from becoming empty must know the status of the circuit on the write side for preventing the memory from becoming empty, making the FIFO even more complex.
Accordingly, there is a need for an improved circuit and method of method of buffering data received in a first clock domain and output in a second clock domain.